import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ListGroupComponent} from "./list-group/list-group.component";
import {InterbankService} from "./interbank.service";
import {NettingCountComponent, NettingCountResultModel} from "./netting-count/netting-count.component";
import {Util} from "../../common/util";
import {Subscription} from "rxjs/Subscription";
import {ChangeMatchComponent} from "./change-match/change-match.component";
import {Observable} from "rxjs/Observable";
import * as _ from "lodash";
import {FileUploadComponent} from "./file-upload/file-upload.component";
import {FileUploaderOptions} from "ng2-file-upload";
import {IBTListColumnDisplayConfigModel, ListComponent} from "./list/list.component";
import * as moment from "moment";
import {ActivatedRoute, Router} from "@angular/router";
import {Action, Store} from "@ngrx/store";
import {InterbankToTransferExchangeDataModel} from "../../actionReducer/interbank-to-transfer/interbank-to-transfer.reducer";
import * as queryString from "query-string";
import {environment} from "../../../environments/environment";

/**
 * 银行间银行间债券交易列表搜索数据模型
 */
export interface IBTSearchModel {
  /**
   * 组合名称
   */
  ownHolderShortName?: string;
  /**
   * 组合代码
   */
  ownHolderAccount?: string;
  /**
   * 交易对手
   */
  direction?: string;
  /**
   * 本方合同状态
   */
  ownContractStatus?: string;
  /**
   * 对方合同状态
   */
  opstContractStatus?: string;
  /**
   * 交易日期
   */
  tradeDate?: string;
  /**
   * 结算日期
   */
  settlementDate?: string;
  /**
   * 业务类型
   */
  tradeType?: string;

  [propName: string]: any;
}

/**
 * 计算条件数据模型
 */
export interface ComputedConditionModel {
  /**
   * 是否允许计算
   */
  allow?: boolean;
  /**
   * 总体错误信息
   */
  totalErrorMessage?: string;
  /**
   * 详细错误信息
   */
  errorMessages?: Array<any>;
  /**
   * 将参与计算的数据
   */
  willComputedData?: Array<any>;

  /**
   * 其他自定义属性
   */
  [propName: string]: any;
}

@Component({
  selector: 'interbank',
  templateUrl: './interbank.component.html',
  styleUrls: ['./interbank.component.scss']
})
export class InterbankComponent implements OnInit, AfterViewInit {
  /**
   * 银行间债券交易分组列表数据
   */
  public groupListData: Array<any> = [];

  /**
   * 银行间债券交易不分组列表数据
   * @type {{list: Array}}
   */
  public listData: any = {list: []};

  /**
   * 导出债券列表数据Excel表的地址，默认导出分组视图的
   * @type {string}
   */
  public downloadUrl = 'otc/v1/chinamoney/bond-trade-groupview-export';

  /**
   * 列表视图显示状态数据映射对象
   * value值为true时表示显示，false表示隐藏
   * @type {{groupList: boolean; ungroupList: boolean}}
   */
  public viewShowStatus = {
    /**
     * 分组视图显示状态，默认显示
     */
    groupList: true,
    /**
     * 部分组视图显示状态，默认隐藏
     */
    ungroupList: false
  };

  /**
   * o32相关列配置
   */
  public o32RefColsConfig: IBTListColumnDisplayConfigModel = {
    trdFundName: false,
    trdTradeType: false,
    trdProductCode: false,
    trdProductName: false,
    trdSettleBalance: false,
    trdPledgeMatchStatus: false
  };

  /**
   * 分组银行间债券交易列表组件
   */
  @ViewChild(ListGroupComponent)
  public listGroupComponent: ListGroupComponent;

  /**
   * 不分组银行间债券交易列表组件
   */
  @ViewChild(ListComponent)
  public listComponent: ListComponent;

  /**
   * 轧差计算组件
   */
  @ViewChild(NettingCountComponent)
  public nettingCountComponent: NettingCountComponent;

  /**
   * 变更匹配模态框
   */
  @ViewChild('settlementComparationModal')
  public settlementComparationModal: ElementRef;

  /**
   * 手动逾期填写模态框
   */
  @ViewChild('overdueModal')
  public overdueModal: ElementRef;

  /**
   * 设置加急处理人模态框
   */
  @ViewChild('urgentModal')
  public urgentModal: ElementRef;

  /**
   * 变更匹配组件
   */
  @ViewChild(ChangeMatchComponent)
  public changeMatchComponent: ChangeMatchComponent;

  /**
   * 成交单附件上传组件
   */
  @ViewChild(FileUploadComponent)
  public uploadFileComponent: FileUploadComponent;

  /**
   * O32质押券比对信息列表模态框
   */
  @ViewChild('pledgeMatchListModal')
  public pledgeMatchListModal: ElementRef;

  /**
   * 将进行轧差计算的数据
   */
  public nettingCountData: NettingCountResultModel;

  /**
   * 将参与轧差计算的数据
   */
  public willNettingCountData: Array<{ [propName: string]: any }>;

  /**
   * 成交单上传附件组件配置数据
   * @type {{url: string}}
   */
  public uploadFileConfig: FileUploaderOptions = {
    url: 'otc/v1/chinamoney/tradeOrderFile',
  };

  /**
   * O32质押券比对信息列表模态框列表数据
   * @type {{}}
   */
  public pledgeMatchModalData: any = {
    trdPledgeInfos: [],
    otcPledgeInfos: []
  };

  /**
   * 将进行变更匹配的数据
   * @type {{otcBondTrade: {}; trdBondTradeList: Array}}
   */
  public changeMatchData = {
    otcBondTrade: {},
    trdBondTradeList: []
  };

  constructor(public service: InterbankService,
              public router: Router,
              public activedRouter: ActivatedRoute,
              public ittStore: Store<InterbankToTransferExchangeDataModel>) {

  }

  ngOnInit(): void {
  }

  ngAfterViewInit(): void {
    Util.$(this.listComponent.fixedTable.nativeElement).css('background', 'white');
    Util.$(this.listComponent.container.nativeElement).css('margin-top', '-20px');
    /**
     * 初始化所有'银行间模块'用到的jQuery插件
     */
    Util.daterangepickerPluginInit(".daterangepicker-plugin", {}, true, true);
    Util.datepickerPluginInit('.datepicker-plugin');
    Util.$("#tradeDate").val('');
    this.select2PluginInit().then(() => {
      this.search();
    });
  }

  /**
   * 切换显示列表视图,视图切换
   */
  public switchListView() {
    this.viewShowStatus.groupList = !this.viewShowStatus.groupList;
    this.viewShowStatus.ungroupList = !this.viewShowStatus.groupList;
    if (this.viewShowStatus.ungroupList) {
      // TODO POC环境后端没有部署不分组列表导出接口，故在此都导出分组列表的数据
      this.downloadUrl = 'otc/v1/chinamoney/bond-trade-groupview-export';
    } else {
      this.downloadUrl = 'otc/v1/chinamoney/bond-trade-groupview-export';
    }
    this.search(true);
  }

  /**
   * 获取当前视图已勾选的数据
   * @returns {Array<any>}
   */
  public getSelectedDatas(): Array<any> {
    const isGroup: boolean = this.viewShowStatus.groupList ? true : false;
    if (isGroup) {
      return _.flatten(this.listGroupComponent.getSelectedDatas());
    } else {
      return this.listComponent.getSelectedDatas();
    }
  }

  /**
   * 初始化select2插件搜索下拉框
   * @returns {Promise<any>}
   */
  public select2PluginInit(): Promise<any> {
    const dealManPromise: Promise<any> = new Promise((resolve, reject) => {
      this.service.getDealManDataList().subscribe((data) => {
        Util.$(this.urgentModal.nativeElement)
          .find('#dealMan')
          .select2({
            data
          });
        resolve(data);
      });
    });
    const fundCodeListPromise: Promise<any> = new Promise((resolve, reject) => {
      this.service.getFundInfoListData().subscribe((data) => {
        data = (data || []).map((item) => {
          return {
            id: item.fundCode,
            text: item.fundName
          };
        });
        const $fundCodeList = Util.$('#fundCodeList').select2({
          data,
          multiple: true,
          closeOnSelect: false
        });
        $fundCodeList.data('select2').$container.css('width', '175px');
        resolve(data);
      });
    });
    const accountListPromise: Promise<any> = new Promise((resolve, reject) => {
      this.service.getOppoHolderAccountListData().subscribe((data) => {
        data = (data || []).map((item) => {
          return {
            id: item.account,
            text: item.shortName
          };
        });
        Util.$('#oppoHolderAccountList').select2({
          data,
          multiple: true,
          closeOnSelect: false
        });
        resolve(data);
      });
    });
    const tagIdListPromise: Promise<any> = new Promise((resolve, reject) => {
      this.service.getFundFavoriteTagIdList().subscribe((data) => {
        if (data && Array.isArray(data.list) && data.list.length > 0) {
          data = data.list.map((item) => {
            return {
              id: item.objid,
              text: item.objname
            };
          });
        } else {
          data = [];
        }
        Util.$('#fundFavoriteTagIdList').select2({
          data,
          multiple: true,
          closeOnSelect: false
        });
        resolve(data);
      });
    });
    return Promise.all([dealManPromise, fundCodeListPromise, accountListPromise, tagIdListPromise]);
  }

  /**
   * 展开全部银行间债券交易列表
   */
  public toggleAllListOpen(): void {
    this.listGroupComponent.toggleAllListOpen();
  }

  /**
   *  折叠全部银行间债券交易列表
   */
  public toggleAllListClose(): void {
    this.listGroupComponent.toggleAllListClose();
  }

  /**
   * 打开轧差计算模态框
   */
  public toggleNettingCountModalOpen(): void {
    this.nettingCountComponent.openModal();
  }

  /**
   * 关闭轧差计算模态框
   */
  public toggleNettingCountModalClose(): void {
    this.nettingCountComponent.closeModal();
  }

  /**
   * 打开变更匹配模态框
   */
  public toggleChangeMatchModalOpen() {
    this.changeMatchComponent.openModal();
  }

  /**
   * 打开手工逾期模态框
   */
  public toggleOverdueModalOpen() {
    return Util.$(this.overdueModal.nativeElement).modal('show');
  }

  /**
   * 关闭手工逾期模态框
   */
  public toggleOverdueModalClose() {
    return Util.$(this.overdueModal.nativeElement).modal('hide');
  }

  /**
   * 打开附件上传模态框
   * @returns {any}
   */
  public toggleFileUploadModalOpen() {
    return this.uploadFileComponent.toggleModalOpen();
  }

  /**
   * 关闭附件上传模态框
   * @returns {any}
   */
  public toggleFileUploadModalClose() {
    return this.uploadFileComponent.toggleModalClose();
  }

  /**
   * 打开发起加急处理模态框
   * @param settlementOrderId
   */
  public toggleUrgentModalOpen(settlementOrderId: string = "") {
    const $modal = Util.$(this.urgentModal.nativeElement);
    const $dealMan = $modal.find('#dealMan');
    this.clearDealMan();
    $dealMan.data('settlementOrderId', settlementOrderId);
    $modal.modal('show');
  }

  /**
   * 关闭发起加急处理模态框
   */
  public toggleUrgentModalClose() {
    const $modal = Util.$(this.urgentModal.nativeElement);
    $modal.modal('hide');
  }

  /**
   * 清空加急处理人选择框
   */
  public clearDealMan() {
    const $modal = Util.$(this.urgentModal.nativeElement);
    const $dealMan = $modal.find('#dealMan');
    const select2Data = $dealMan.data('select2');
    if (select2Data) {
      $dealMan.select2("val", "");
    } else {
      $dealMan.val('');
    }
    $dealMan.data('settlementOrderId', '');
  }

  /**
   * 打开O32质押券比对信息列表模态框
   */
  public togglePledgeMatchModalOpen() {
    const $modal = Util.$(this.pledgeMatchListModal.nativeElement);
    this.clearPledgeMatchModalData();
    $modal.modal('show');
  }

  /**
   * 关闭O32质押券比对信息列表模态框
   */
  public togglePledgeMatchModalClose() {
    const $modal = Util.$(this.pledgeMatchListModal.nativeElement);
    this.clearPledgeMatchModalData();
    $modal.modal('hide');
  }

  /**
   * 清空O32质押券比对信息列表模态框关联的数据
   */
  public clearPledgeMatchModalData() {
    this.pledgeMatchModalData = {
      trdPledgeInfos: [],
      otcPledgeInfos: []
    };
  }

  /**
   * 获取银行间债券交易列表数据并渲染列表
   * @param {boolean} keepOpen 是否列表当前打开关闭状态
   * @returns {Subscription}
   */
  public search(keepOpen: boolean = false) {
    if (this.viewShowStatus.groupList) {
      return this.getGroupListData(this.wrapperSearchModel()).add(() => {
        if (keepOpen) {
          const fundCodeList: string[] = this.listGroupComponent.getOpenListComponentFundCodeList();
          setTimeout(() => {
            this.listGroupComponent.listComponents
              .filter(item => fundCodeList.indexOf(item.data.fundCode) !== -1)
              .forEach(item => item.fold = false);
          }, 0);
        }
      });
    } else {
      return this.getListData(this.wrapperSearchModel());
    }
  }

  /**
   * 自动刷新数据渲染列表,默认是每1000毫秒，也就是每1秒
   * @param interval 每隔多少毫秒自动刷新数据渲染列表
   * @returns {Subscription}
   */
  public autoSearch(interval: number = 1000): Subscription {
    return Observable.interval(interval)
      .subscribe(() => {
        this.search(true);
      });
  }

  /**
   * 将所有搜索条件框重置为空
   */
  public resetSearch() {
    Util.resetInputs('.ibt-search-input');
  }

  /**
   * 银行间债券交易列表------轧差计算
   * @returns {Subscription}
   */
  public nettingCount(): Subscription {
    const isGroup: boolean = this.viewShowStatus.groupList;
    const datas = isGroup ? _.flatten(this.listGroupComponent.getSelectedDatas()) : this.listComponent.getSelectedDatas();
    let messageText = '';
    const returnBack: Subscription = Observable.from([]).subscribe();
    const {allow, totalErrorMessage, errorMessages, willComputedData} = this.computedNettingCountCondition(datas);
    const toTransferModuleCondition = this.computedToTransferModuleCondition(datas);
    this.willNettingCountData = [];
    if (totalErrorMessage != null && totalErrorMessage.length > 0) {
      window['swal']({
        title: "提示",
        text: `<div>${totalErrorMessage}</div>`,
        html: true,
        type: "warning"
      });
      return returnBack;
    }
    if (!allow) {
      messageText = _.flatten(errorMessages, true).map(item => `<li>${item}</li>`).join("");
      window['swal']({
        title: "提示",
        text: `<div style="max-height: 250px;overflow-y: auto;text-align: left;"><ol>${messageText}</ol></div>`,
        html: true,
        type: "warning"
      });
      return returnBack;
    }
    this.willNettingCountData = willComputedData;
    return this.intoTransferModuleAlert(toTransferModuleCondition).subscribe((isCanContinue) => {
      if (isCanContinue) {
        this.doNettingCount(this.willNettingCountData);
      }
    });
  }

  /**
   * 发送数据到服务器端，进行轧差（预览）计算
   * @param data
   * @returns {Subscription}
   */
  public doNettingCount(data: Array<any>): Subscription {
    const orderSerialNos = data.map((item) => {
      return {orderSerialNo: item.orderSerialNo};
    });
    return this.service.nettingCount(orderSerialNos).subscribe(result => {
      this.nettingCountData = result || {};
      this.toggleNettingCountModalOpen();
    });
  }

  /**
   * 计算轧差条件
   * @param datas
   * @returns {ComputedConditionModel}
   */
  public computedNettingCountCondition(datas: Array<any>): ComputedConditionModel {
    const result: ComputedConditionModel = {
      allow: false,
      totalErrorMessage: '',
      errorMessages: [],
      willComputedData: []
    };
    const length = datas.length;
    const base = datas[0];
    const todayStr = moment(new Date()).format('YYYYMMDD');
    if (length <= 0) {
      result.totalErrorMessage = "请选择要进行轧差计算的明细！";
      return result;
    }
    for (let i = 0; i < length; i++) {
      const item = datas[i];
      const errors = [];
      if (item.tradeId == null) {
        errors.push(`您当前选择的第${i + 1}单据没有成交单号，不能参与轧差计算`);
        result.errorMessages.push(errors);
        break;
      } else {
        if (item.fundCode !== base.fundCode) {
          result.errorMessages.push(`成交编号为：${item.tradeId}的单据和成交编号为：${base.tradeId}的单据不是同一基金，不能参与轧差计算`);
        }
        if (item.overdueByHand === "Y") {
          errors.push(`成交编号为：${item.tradeId}的单据已经逾期，不能参与轧差计算`);
        }
        if (item.cancelByHand === "Y") {
          errors.push(`成交编号为：${item.tradeId}的单据已经作废，不能参与轧差计算`);
        }
        if (`${item.settlementDate}` !== todayStr) {
          errors.push(`成交编号为：${item.tradeId}的单据的结算日期不是今天，不能参与轧差计算`);
        }
        if (item.settlementDate !== base.settlementDate) {
          errors.push(`成交编号为：${item.tradeId}的单据和成交编号为：${base.tradeId}的单据的结算日期不是同一天，不能参与轧差计算`);
        }
        if (errors.length > 0) {
          result.errorMessages.push(errors);
        }
      }
    }
    result.allow = result.errorMessages.every(item => item.length <= 0);
    if (result.allow) {
      result.willComputedData = datas;
    }
    return result;
  }


  /**
   * 根据跳转到划款指令管理模块的条件数据对象，决定是提示进入划款指令管理模块，还是强制进入
   * @param condition
   * @returns {any} 如果Observable发射出true代表着可以进行下一步操作，反正则相反
   */
  public intoTransferModuleAlert(condition: ComputedConditionModel): Observable<boolean> {
    return Observable.create((ob) => {
      let messageTexts = '';
      const transferInstructionIds: Array<string> = condition.willComputedData.map(item => item.transferInstructionId);
      if (!condition.allow) {
        messageTexts += `<p>以下交易单号对应的单据已经轧差，建议取消其划款指令再进行轧差：</p>`;
        messageTexts += `<ol>`;
        messageTexts += condition.willComputedData.map(item => `<li class="text-green">${item.tradeId}</li>`).join('');
        messageTexts += `<ol>`;
        window['swal']({
          title: '提示',
          text: `<div style="max-height: 250px;overflow-y: auto;text-align: left;">${messageTexts}</div>`,
          html: true,
          type: "warning",
          showCancelButton: true,
          confirmLoadingButtonColor: '#DD6B55',
          cancelButtonText: "忽略并继续",
          confirmButtonText: "接受",
          allowOutsideClick: false
        }, (isConfirm) => {
          if (isConfirm) {
            this.forwardToTransferInstructionModule(transferInstructionIds);
          } else {
            ob.next(true);
          }
        });
      } else {
        ob.next(true);
      }
    });
  }

  /**
   * 计算跳转到划款指令管理模块的条件
   * @param datas
   * @returns {ComputedConditionModel}
   */
  public computedToTransferModuleCondition(datas: Array<any>): ComputedConditionModel {
    const result: ComputedConditionModel = {
      allow: false,
      errorMessages: [],
      willComputedData: []
    };
    datas.forEach((item) => {
      if (item.nettingStatus === "Y") {
        result.willComputedData.push(item);
        result.errorMessages.push(`成交编号为：${item.tradeId}的单据已经轧差过了`);
      }
    });
    if (result.errorMessages.length <= 0) {
      result.allow = true;
      result.willComputedData = datas;
    }
    return result;
  }

  /**
   * 重置轧差计算组件初始化数据
   * @param clearWillNettingCountData 是否立即清空轧差计算的数据
   */
  public resetNettingCountData(clearWillNettingCountData: boolean) {
    if (clearWillNettingCountData === true) {
      this.nettingCountData = {sch: {list: []}, cbc: {list: []}};
    }
  }

  /**
   * 保存轧差计算结果的回调，如果成功则刷新列表
   * @param status
   */
  public saveNettingCountDataCallback(status: boolean) {
    if (status === true) {
      this.search(true);
    }
  }

  /**
   * 进入划款指令管理模块
   * @param transferInstructionIds 划款指令ID组成的数组
   */
  public forwardToTransferInstructionModule(transferInstructionIds: string[]) {
    const action: Action = {
      type: 'QUERY',
      payload: {
        transferInstructionIds
      }
    };
    this.ittStore.dispatch(action);
    this.router.navigateByUrl(`pages/transferInstruction/transferList/exchange/true`);
  }

  /**
   * 银行间债券交易列表------确定交收对比询问
   */
  public settlementComparationConfirm() {
    const isGroup: boolean = this.viewShowStatus.groupList;
    const selectDatas = isGroup ? _.flatten(this.listGroupComponent.getSelectedDatas()) : this.listComponent.getSelectedDatas();
    const condition: ComputedConditionModel = this.computedSettlementComparationCondition(selectDatas);
    let messageText: Array<string> = [];
    if (!condition.allow) {
      if (condition.errorMessages.length <= 0) {
        window['swal']('提示', condition.totalErrorMessage, 'warning');
      } else {
        messageText.push('<div style="max-height: 250px;overflow-y: auto;text-align: left;"><ol>');
        messageText = messageText.concat(_.flatten(condition.errorMessages).map(message => `<li>${message}</li>`));
        messageText.push('</ol></div>');
        window['swal']({
          title: '提示',
          text: messageText.join(''),
          type: 'warning',
          html: true
        });
      }
      return;
    }
    window['swal']({
      title: '提示',
      text: '确认交收比对吗？',
      type: 'info',
      showCancelButton: true,
      closeOnConfirm: false,
      disableButtonsOnConfirm: true,
      showLoaderOnConfirm: true,
      confirmLoadingButtonColor: '#DD6B55',
      cancelButtonText: "否",
      confirmButtonText: "是"
    }, () => {
      const settlementOrderIdList: Array<any> = _.map(_.flatten(condition.willComputedData), function (item) {
        return {settlementOrderId: item.settlementOrderId};
      });
      this.settlementComparation(settlementOrderIdList).subscribe((data) => {
        if (data === 'success') {
          this.search(true);
          setTimeout(() => {
            window['swal']('提示', '交收比对成功！', 'success');
          }, 0);
        }
      });
    });
  }

  /**
   * 计算交收比对条件
   * @param datas
   * @returns {ComputedConditionModel}
   */
  public computedSettlementComparationCondition(datas: Array<any>): ComputedConditionModel {
    const result: ComputedConditionModel = {
      allow: false,
      totalErrorMessage: '',
      errorMessages: [],
      willComputedData: []
    };
    const length: number = datas.length;
    if (length <= 0) {
      result.totalErrorMessage = '请选择要进行交收比对操作的单据！';
      return result;
    }
    datas.forEach((item) => {
      const errors: Array<string> = [];
      if (item.settlementOrderId == null) {
        errors.push(`成交编号为：${item.tradeId}的单据没有结算数据，不能参与交收比对操作`);
      }
      if (item.trdSettleCompareStatus === 'Y') {
        errors.push(`成交编号为：${item.tradeId}的单据已经交收比对过了，不能再参与交收比对操作`);
      }
      if (item.cancelByHand === "Y") {
        errors.push(`成交编号为：${item.tradeId}的单据已经作废，不能再参与交收比对操作`);
      }
      if (item.overdueByHand === "Y") {
        errors.push(`成交编号为：${item.tradeId}的单据已经逾期，不能再参与交收比对操作`);
      }
      if (errors.length > 0) {
        result.errorMessages.push(errors);
      }
    });
    if (result.errorMessages.length <= 0) {
      result.allow = true;
      result.willComputedData = datas;
    }
    return result;
  }

  /**
   * 银行间债券交易列表------交收对比
   * @param settlementOrderIdList
   * @returns {Observable<any>}
   */
  public settlementComparation(settlementOrderIdList: Array<any>): Observable<any> {
    return this.service.settlementComparation(settlementOrderIdList);
  }


  /**
   * 导出银行间债券交易列表数据
   * @param {string} url
   */
  public exportData(url: string) {
    const search = this.wrapperSearchModel();
    search['token'] = sessionStorage.getItem('username');
    const queryParamStr = queryString.stringify(search);
    url = environment.server + url + '?' + queryParamStr;
    const link: HTMLAnchorElement = window.document.createElement('a');
    link.href = url;
    link.setAttribute('download', '');
    link.click();
    window.URL.revokeObjectURL(link.href);
    link.remove();
  }

  /**
   * 银行间债券交易列表-----手工作废单据询问
   */
  public invalidBillConfirm() {
    const isGroup: boolean = this.viewShowStatus.groupList ? true : false;
    const selectDatas = isGroup ? _.flatten(this.listGroupComponent.getSelectedDatas()) : this.listComponent.getSelectedDatas();
    const condition: ComputedConditionModel = this.computedInvalidBillCondition(selectDatas);
    const warningMessages: Array<string> = [];
    let settlementOrderIds: Array<string> = [];
    const messageTexts: Array<string> = ['是否将以下成交编号对应的单据进行手工作废？'];
    if (!condition.allow) {
      if (condition.errorMessages.length <= 0) {
        warningMessages.push(`${condition.totalErrorMessage}`);
      } else {
        warningMessages.push(`<div style="max-height: 250px;overflow-y: auto;text-align: left;" class="text-warning"><ol>`);
        condition.errorMessages.forEach(error => warningMessages.push(`<li>${error}</li>`));
        warningMessages.push(`</div><\ol>`);
      }
      window['swal']({
        title: '提示',
        type: 'warning',
        text: warningMessages.join(''),
        html: true
      });
      return;
    } else {
      settlementOrderIds = _.map(selectDatas, 'settlementOrderId');
      messageTexts.push('<div style="max-height: 250px;overflow-y: auto;text-align: left;padding-left:15px;"><ol>');
      settlementOrderIds.forEach(id => messageTexts.push(`<li class="text-green">${id}</li>`));
      messageTexts.push('</div></ol>');
      window['swal']({
        title: '提示',
        text: messageTexts.join(''),
        type: 'info',
        showCancelButton: true,
        closeOnConfirm: false,
        disableButtonsOnConfirm: true,
        showLoaderOnConfirm: true,
        confirmLoadingButtonColor: '#DD6B55',
        cancelButtonText: "否",
        confirmButtonText: "是",
        html: true
      }, () => {
        this.invalidBill(_.map(settlementOrderIds, (item) => {
          return {
            settlementOrderId: item
          };
        })).subscribe((data) => {
          if (data != null || data === 'success') {
            setTimeout(() => {
              window['swal']("提示", '手工作废单据操作成功!', "success");
              this.search(true);
            }, 0);
          }
        });
      });
    }
  }

  /**
   * 银行间债券交易列表-----手工作废单据
   * @param settlementOrderIds
   * @returns {Observable<any>}
   */
  public invalidBill(settlementOrderIds: Array<any>): Observable<any> {
    return this.service.invalidBill(settlementOrderIds);
  }

  /**
   * 计算手工作废条件
   * @param datas
   * @returns {ComputedConditionModel}
   */
  public computedInvalidBillCondition(datas: Array<any>): ComputedConditionModel {
    const result: ComputedConditionModel = {
      allow: false,
      totalErrorMessage: '',
      errorMessages: [],
      willComputedData: []
    };
    if (datas.length <= 0) {
      result.totalErrorMessage = '请选择要进行手工作废的单据！';
      return result;
    }
    datas.forEach((item) => {
      const errors = [];
      if (item.settlementOrderId == null) {
        errors.push(`成交编号为：${item.tradeId}的单据没有结算数据，不能参与手工作废操作`);
      }
      if (item.cancelByHand === "Y") {
        errors.push(`成交编号为：${item.tradeId}的单据已经作废，不能再参与手工作废操作`);
      }
      if (item.overdueByHand === "Y") {
        errors.push(`成交编号为：${item.tradeId}的单据已经逾期，不能再参与手工作废操作`);
      }
      if (errors.length > 0) {
        result.errorMessages.push(errors);
      }
    });
    if (result.errorMessages.length > 0) {
      return result;
    }
    result.willComputedData = datas;
    result.allow = true;
    return result;
  }

  /**
   * 银行间债券交易列表-----取消手工作废单据询问
   */
  public calcelInvalidBillConfirm() {
    const isGroup: boolean = this.viewShowStatus.groupList ? true : false;
    const selectDatas = isGroup ? _.flatten(this.listGroupComponent.getSelectedDatas()) : this.listComponent.getSelectedDatas();
    const condition: ComputedConditionModel = this.computedCancelInvalidBillCondition(selectDatas);
    const warningMessages: Array<string> = [];
    let settlementOrderIds: Array<string> = [];
    const messageTexts: Array<string> = ['是否将以下成交编号对应的单据进行取消手工作废操作？'];
    if (!condition.allow) {
      if (condition.errorMessages.length <= 0) {
        warningMessages.push(`${condition.totalErrorMessage}`);
      } else {
        warningMessages.push(`<div style="max-height: 250px;overflow-y: auto;text-align: left;" class="text-warning"><ol>`);
        condition.errorMessages.forEach(error => warningMessages.push(`<li>${error}</li>`));
        warningMessages.push(`</div><\ol>`);
      }
      window['swal']({
        title: '提示',
        type: 'warning',
        text: warningMessages.join(''),
        html: true
      });
      return;
    } else {
      settlementOrderIds = _.map(selectDatas, 'settlementOrderId');
      messageTexts.push('<div style="max-height: 250px;overflow-y: auto;text-align: left;padding-left:15px;"><ol>');
      settlementOrderIds.forEach(id => messageTexts.push(`<li class="text-green">${id}</li>`));
      messageTexts.push('</div></ol>');
      window['swal']({
        title: '提示',
        text: messageTexts.join(''),
        type: 'info',
        showCancelButton: true,
        closeOnConfirm: false,
        disableButtonsOnConfirm: true,
        showLoaderOnConfirm: true,
        confirmLoadingButtonColor: '#DD6B55',
        cancelButtonText: "否",
        confirmButtonText: "是",
        html: true
      }, () => {
        this.cancelInvalidBill(_.map(settlementOrderIds, item => {
          return {
            settlementOrderId: item
          };
        })).subscribe((data) => {
          if (data != null || data === 'success') {
            setTimeout(() => {
              window['swal']("提示", '取消手工作废单据操作成功!', "success");
              this.search(true);
            }, 0);
          }
        });
      });
    }
  }

  /**
   * 计算取消手工作废条件
   * @param datas
   * @returns {ComputedConditionModel}
   */
  public computedCancelInvalidBillCondition(datas: Array<any>): ComputedConditionModel {
    const result: ComputedConditionModel = {
      allow: false,
      totalErrorMessage: '',
      errorMessages: [],
      willComputedData: []
    };
    if (datas.length <= 0) {
      result.totalErrorMessage = '请选择要进行取消手工作废的单据！';
      return result;
    }
    datas.forEach((item) => {
      const errors = [];
      if (item.cancelByHand !== "Y") {
        errors.push(`成交编号为：${item.tradeId}的单据未曾手工作废过，不能再参与取消手工作废操作`);
      }
      if (item.overdueByHand === "Y") {
        errors.push(`成交编号为：${item.tradeId}的单据已经逾期，不能再参与取消手工作废操作`);
      }
      if (errors.length > 0) {
        result.errorMessages.push(errors);
      }
    });
    if (result.errorMessages.length > 0) {
      return result;
    }
    result.willComputedData = datas;
    result.allow = true;
    return result;
  }

  /**
   * 银行间债券交易列表-----取消手工作废单据
   * @param settlementOrderIds
   * @returns {Observable<any>}
   */
  public cancelInvalidBill(settlementOrderIds: Array<any>): Observable<any> {
    return this.service.cancelInvalidBill(settlementOrderIds);
  }

  /**
   * 计算手工逾期条件
   * @param datas
   * @returns {ComputedConditionModel}
   */
  public computedOverdueCondition(datas: Array<any>): ComputedConditionModel {
    const result: ComputedConditionModel = {
      allow: false,
      totalErrorMessage: '',
      errorMessages: [],
      willComputedData: []
    };
    if (datas.length <= 0) {
      result.totalErrorMessage = '请选择要进行手工逾期操作的单据！';
      return result;
    } else if (datas.length > 1) {
      result.totalErrorMessage = '最多只能进行手工逾期一条单据！';
      return result;
    } else {
      datas.forEach((data) => {
        if (data.overdueByHand === "Y") {
          result.errorMessages.push(`成交编号为：${data.tradeId}的单据已经手工逾期过,不能再进行逾期操作！`);
        }
        if (data.cancelByHand === "Y") {
          result.errorMessages.push(`成交编号为：${data.tradeId}的单据已经手工作废过，不能再进行逾期操作！`);
        }
        if (data.settlementOrderId == null) {
          result.errorMessages.push(`成交编号为：${data.tradeId}的单据没有结算数据，不能进行逾期操作！`);
        }
      });
    }
    if (result.errorMessages.length <= 0) {
      result.allow = true;
      result.willComputedData = datas;
    }
    return result;
  }

  /**
   * 根据手工逾期条件决定是否打开手工逾期模态框
   */
  public toggleOverdueModalOpenByCondition() {
    const isGroup: boolean = this.viewShowStatus.groupList ? true : false;
    const selectedDatas = isGroup ? this.listGroupComponent.getSelectedDatas() : this.listComponent.getSelectedDatas();
    const condition: ComputedConditionModel = this.computedOverdueCondition(_.flatten(selectedDatas));
    const willOverdueId = _.map(condition.willComputedData, "settlementOrderId")[0];
    const $overdueDateEl = Util.$(this.overdueModal.nativeElement).find('#overdueDate');
    const messageTexts: Array<string> = [];
    $overdueDateEl.attr('data-settlement-order-id', "");
    if (condition.allow === true) {
      this.toggleOverdueModalOpen();
      $overdueDateEl.attr('data-settlement-order-id', willOverdueId);
    } else {
      if (condition.errorMessages.length <= 0) {
        window['swal']("提示", condition.totalErrorMessage, "warning");
      } else {
        messageTexts.push('<div style="max-height: 250px;overflow-y: auto;text-align: left;padding-left:15px;"><ol>');
        condition.errorMessages.forEach(error => messageTexts.push(`<li class="text-warning">${error}</li>`));
        messageTexts.push('</div></ol>');
        window['swal']({
          title: '提示',
          text: messageTexts.join(''),
          type: 'warning',
          html: true
        });
      }
      return;
    }
  }

  /**
   * 银行间债券交易列表-----手动逾期单据
   * @returns {Subscription}
   */
  public overdue(): Subscription {
    const $overdueDateEl = Util.$(this.overdueModal.nativeElement).find('#overdueDate');
    let date: string = $overdueDateEl.val();
    const settlementOrderId: string = $overdueDateEl.attr('data-settlement-order-id');
    date = ((date != null) ? date : "").replace(/-/g, "");
    return this.service.overdue([{date, settlementOrderId}]).subscribe(data => {
      this.toggleOverdueModalClose();
      if (data === 'success') {
        this.search(true);
        window['swal']("提示", "手工逾期操作成功！", "success");
      }
    });
  }

  /**
   * 弹出是否取消逾期询问模态框
   */
  public cancelOverdueConfirm() {
    const isGroup: boolean = this.viewShowStatus.groupList ? true : false;
    const targetDatas = isGroup ? this.listGroupComponent.getSelectedDatas() : this.listComponent.getSelectedDatas();
    const selectedDatas: Array<any> = _.flatten(targetDatas);
    const settlementOrderIds: Array<string> = _.map(selectedDatas, 'settlementOrderId');
    const condition: ComputedConditionModel = this.computedCancelOverdueCondition(selectedDatas);
    let messageTexts: Array<string> = [`
                        <div style="max-height: 250px;overflow-y: auto;text-align: left;padding-left:15px;">
                        <ol>`];
    if (!condition.allow) {
      messageTexts = messageTexts.concat(condition.errorMessages.map((errorMess) => {
        return `<li class="text-warning">${errorMess}</li>`;
      }));
      messageTexts.push(`</ol></div>`);
      window['swal']({
        title: '提示',
        text: condition.totalErrorMessage.length > 0 ? condition.totalErrorMessage : messageTexts.join(''),
        type: 'warning',
        html: true
      });
    } else {
      messageTexts.push('是否将以下成交编号对应的单据进行取消手工逾期操作？');
      messageTexts = messageTexts.concat(selectedDatas.map((item) => {
        return `<li class="text-green">${item.tradeId}</li>`;
      }));
      messageTexts.push(`</ol></div>`);
      window['swal']({
        title: '提示',
        text: messageTexts.join(''),
        type: 'info',
        showCancelButton: true,
        closeOnConfirm: false,
        disableButtonsOnConfirm: true,
        showLoaderOnConfirm: true,
        confirmLoadingButtonColor: '#DD6B55',
        cancelButtonText: "否",
        confirmButtonText: "是",
        html: true
      }, () => {
        this.cancelOverdue(_.map(settlementOrderIds, (item) => {
          return {
            settlementOrderId: item
          };
        }));
      });
    }
  }

  /**
   * 计算取消手工逾期操作条件模型
   * @param datas
   * @returns {ComputedConditionModel}
   */
  public computedCancelOverdueCondition(datas: Array<any>): ComputedConditionModel {
    const condition: ComputedConditionModel = {
      allow: false,
      totalErrorMessage: "",
      errorMessages: [],
      willComputedData: []
    };
    if (datas.length <= 0) {
      condition.totalErrorMessage = "请选择要进行取消手工逾期操作的单据！";
      condition.errorMessages.push(condition.totalErrorMessage);
    } else {
      datas.forEach((data) => {
        if (data.overdueByHand !== "Y") {
          condition.errorMessages.push(`成交编号为：${data.tradeId}的单据没有手工逾期过，不能参与取消手工逾期操作`);
        }
        if (data.cancelByHand === "Y") {
          condition.errorMessages.push(`成交编号为：${data.tradeId}的单据已经手工作废过，不能参与取消手工逾期操作`);
        }
      });
    }
    if (condition.totalErrorMessage.length <= 0 && condition.errorMessages.length <= 0) {
      condition.willComputedData = datas;
      condition.allow = true;
    }
    return condition;
  }

  /**
   * 取消手动逾期，支持批量
   * @param settlementOrderIds
   * @returns {Subscription}
   */
  public cancelOverdue(settlementOrderIds: Array<any>): Subscription {
    return this.service.cancelOverdue(settlementOrderIds).subscribe(() => {
      window['swal'](' 提示', '取消手工逾期成功！', 'success');
      this.search(true);
    });
  }

  /**
   * 将用户输入所有搜索值包装成为一个搜索数据模型对象
   * @returns {IBTSearchModel}
   */
  public wrapperSearchModel(): IBTSearchModel {
    const $ = window["$"];
    const data: IBTSearchModel = {};
    $(".ibt-search-input").each((index, item) => {
      const $item = Util.$(item);
      const type = item.type;
      const id = item.id;
      const value = item.value;
      const select2 = $item.data('select2');
      const daterangepicker = $item.data('daterangepicker');
      if (id && id !== "") {
        if (select2 != null) {
          data[id] = ($item.select2('val') || []).join(',');
        } else if (daterangepicker != null) {
          data[`${id}Begin`] = (value != null && value.length > 0 ) ? daterangepicker.startDate.format('YYYYMMDD') : "";
          data[`${id}End`] = (value != null && value.length > 0 ) ? daterangepicker.endDate.format('YYYYMMDD') : "";
        } else {
          if (type === 'text' || type === 'select' || type === 'select-one') {
            data[id] = value;
          } else if (type === 'checkbox') {
            data[id] = item.checked ? value : "";
          }
        }
      }
    });
    return data;
  }

  /**
   * 获取银行间债券交易分组列表数据
   * @param {IBTSearchModel} search 搜索条件模型对象
   * @returns {Subscription}
   */
  public getGroupListData(search: IBTSearchModel = {}): Subscription {
    return this.service.getGroupListData(search).subscribe(result => {
      this.groupListData = ((result != null && result.data != null) ? result.data : []);
    });
  }

  /**
   * 获取银行间债券交易不分组列表数据
   * @param search 搜索条件模型对象
   * @returns {Subscription}
   */
  public getListData(search: IBTSearchModel = {}): Subscription {
    return this.service.getListData(search).subscribe(result => {
      this.listData.list = ((result != null && result.data != null && result.data.list != null) ? result.data.list : []);
      this.listComponent.unSelectAll();
      setTimeout(() => {
        this.listComponent.resetFixedTableLayout();
      }, 0);
    });
  }

  /**
   * 设置成交单上传附件历史
   * @param uploadFileObj
   */
  public setUploadedFileList(uploadFileObj: any) {
    this.uploadFileComponent.setUploadedFileList(uploadFileObj.orderSerialNo, uploadFileObj.tradeOrderFileId, uploadFileObj.fileName);
    this.toggleFileUploadModalOpen();
  }

  /**
   * 删除附件回调
   * @param uploadSuccess
   */
  public uploadFileCallback(uploadSuccess: boolean) {
    if (uploadSuccess) {
      this.search(true);
    }
  }

  /**
   * 删除附件回调
   * @param removeSuccess
   */
  public removeFileCallback(removeSuccess: boolean) {
    if (removeSuccess) {
      this.search(true);
    }
  }

  /**
   * 根据交易单ID来删除列表明细对应的附件
   * @param orderSerialNo
   */
  public removeFile(orderSerialNo: string) {
    window['swal']({
      title: '提示',
      text: `是否删除交易单附件！`,
      type: 'info',
      showCancelButton: true,
      closeOnConfirm: false,
      disableButtonsOnConfirm: true,
      showLoaderOnConfirm: true,
      confirmLoadingButtonColor: '#DD6B55',
      cancelButtonText: "否",
      confirmButtonText: "是",
      html: true
    }, () => {
      this.service.removeFile(orderSerialNo).subscribe((data) => {
        try {
          if (data != null && data.code === 0) {
            this.removeFileCallback(true);
            window["swal"]("提示", "附件删除成功！", "success");
          } else {
            setTimeout(() => {
              window["swal"]("提示", "附件删除失败！", "error");
            }, 0);
          }
        } catch (e) {
          setTimeout(() => {
            window["swal"]("提示", "附件删除失败！", "error");
          }, 0);
        }
      });
    });
  }


  /**
   *  设置加急事件处理人
   */
  public urgent() {
    const $el = Util.$(this.urgentModal.nativeElement).find('#dealMan');
    const dealMan = $el.select2('val');
    const settlementOrderId = $el.data('settlementOrderId');
    return this.service.urgent([{dealMan, settlementOrderId}]).subscribe((data) => {
      if (data || data === 'success') {
        this.search(true);
        this.toggleUrgentModalClose();
        window['swal']('提示', '发起加急处理成功！', 'success');
      } else {
        window['swal']('提示', `发起加急处理失败！`, 'error');
      }

    });
  }

  /**
   * 计算出是否允许变更匹配的条件的模型数据
   * @param datas
   * @returns {ComputedConditionModel}
   */
  public computedChangeMatchCondition(datas: Array<any>): ComputedConditionModel {
    const condition: ComputedConditionModel = {
      allow: false,
      totalErrorMessage: "",
      errorMessages: [],
      willComputedData: []
    };
    if (datas.length <= 0) {
      condition.totalErrorMessage = "请选择一条要进行变更匹配的单据！";
      return condition;
    }
    if (datas.length > 1) {
      condition.totalErrorMessage = "每次最多一条单据进行变更匹配操作！";
      return condition;
    }
    datas.forEach((item) => {
      if (item.cancelByHand === "Y") {
        condition.errorMessages.push(`目标单据已经手工作废过，不可以进行变更匹配操作!`);
      }
      if (item.overdueByHand === "Y") {
        condition.errorMessages.push(`目标单据已经手工逾期过，不可以进行变更匹配操作!`);
      }
    });
    if (condition.errorMessages.length <= 0) {
      condition.allow = true;
      condition.willComputedData = datas;
    }
    return condition;
  }

  /**
   * 根据计算出的变更匹配条件模型决定是否打开变更匹配模态框
   */
  public openChangeMatchModalByCondition() {
    const selectedDatas: Array<any> = this.getSelectedDatas();
    const condition: ComputedConditionModel = this.computedChangeMatchCondition(selectedDatas);
    const messageTexts: Array<string> = [];
    if (!condition.allow) {
      if (condition.errorMessages.length <= 0) {
        window['swal']('提示', `${condition.totalErrorMessage}`, 'warning');
      } else {
        messageTexts.push('<div style="max-height: 250px;overflow-y: auto;text-align: left;padding-left:15px;"><ol>');
        condition.errorMessages.forEach(error => messageTexts.push(`<li class="text-warning">${error}</li>`));
        messageTexts.push('</div></ol>');
        window['swal']({
          title: '提示',
          text: messageTexts.join(''),
          type: 'warning',
          html: true
        });
      }
    } else {
      const computedData = condition.willComputedData[0];
      this.service
        .getChangeMatchData(computedData.orderSerialNo)
        .subscribe((data) => {
          if (data != null) {
            this.changeMatchData = data || [];
            setTimeout(() => {
              this.toggleChangeMatchModalOpen();
            }, 0);
          }
        });
    }
  }

  /**
   * 保存变更匹配后的回调
   * @param status
   */
  public changeMatchCallback(status: boolean) {
    if (status) {
      this.search(true);
      this.changeMatchComponent.closeModal();
      window['swal']('提示', '变更匹配成功！', 'success');
    } else {
      window['swal']('提示', '变更匹配失败！', 'errors');
    }
  }


  /**
   * 设置O32质押券比对信息列表模态框的数据并打开
   * @param orderSerialNo
   */
  public setAndOpenPledgeMatchModal(orderSerialNo: string) {
    this.clearPledgeMatchModalData();
    this.service
      .getPledgeAllData(orderSerialNo)
      .subscribe((data) => {
        this.togglePledgeMatchModalOpen();
        if (data != null) {
          this.pledgeMatchModalData.otcPledgeInfos = data.otcPledgeInfos || [];
          this.pledgeMatchModalData.trdPledgeInfos = data.trdPledgeInfos || [];
        }
      });
  }
}
